use serde::Serialize;
use serde::Deserialize;
use lazy_static::lazy_static;
use std::sync::Mutex;
use std::fs::File;
use std::io::{BufRead, BufReader, Error, ErrorKind, Write};

pub const file_path: &str = "data.txt";

#[derive(Serialize,Clone,Deserialize,Debug)]
pub struct Item{
    pub id: u32,
    pub title: String,
    pub desc: String,
    pub create_time: String,
    pub finish_time: String,
    pub is_star: bool,
    pub is_finish: bool
}

impl Item{
    pub fn new(id: u32, title: String, desc: String, create_time: String, finish_time: String) -> Item{
        Item{
            id,
            title,
            desc,
            create_time,
            finish_time,
            is_star: false,
            is_finish: false
        }
    }

    pub fn build(id: u32, title: String) -> Item {
        Item {
            id,
            title,
            desc: String::new(),
            create_time: String::new(), 
            finish_time: String::new(), 
            is_star: false,
            is_finish: false
        }
    }
}

lazy_static! {
    //全局静态变量，使用mutex加锁（必须），提供线程安全的访问和修改内部数据的能力 用于在线程间实现共享可变状态的同步访问
    static ref ITEMS: Mutex<Vec<Item>> = Mutex::new(Vec::new());
}


pub fn init_items() {
    //使用lock()加锁，当生命周期结束时，会自动释放锁
    let mut items = ITEMS.lock().unwrap();


    match read_items_from_file() {
        Ok(read_items) => *items = read_items,
        Err(_) => {
            items.push(Item::build(1,String::from("title1")));
            items.push(Item::build(2,String::from("title2")));
            items.push(Item::build(3,String::from("title3")));
        }
    }
}

pub fn list_all() -> Vec<Item> {
    let items = ITEMS.lock().unwrap();
    items.to_vec()
}

pub fn remove(i: u32) {
    let mut items = ITEMS.lock().unwrap();
    items.retain(|n| n.id != i);
}

pub fn add(item: Item){
    let mut items = ITEMS.lock().unwrap();
    items.push(item);
}

pub fn updata(item: Item){
    let mut items = ITEMS.lock().unwrap();
    for i in 0..items.len() {
        if items[i].id == item.id {
            items[i] = item.clone();
        }
    }
    let _ = write_items_to_file(&items);

}

pub fn list_star() -> Vec<Item> {
    let items = ITEMS.lock().unwrap();
    let mut star: Vec<Item> = Vec::new();
    //items是一个MutexGuard对象。需要解引用获取原始类型
    //MutexGuard 对象拥有对内部数据的独占访问权，但是foreach会导致所有权转移，因此所以不能直接将其解引用并移出值，需要改用他的借用
    for item in &*items {
        if item.is_star&&(!item.is_finish) {
            star.push(item.clone());
        }
    }
    star
}
pub fn list_not_finish() -> Vec<Item> {
    let items = ITEMS.lock().unwrap();
    let mut not_finish: Vec<Item> = Vec::new();
    let mut star: Vec<Item> = Vec::new();

    for item in &*items {
        if !item.is_finish {
            if item.is_star {
                star.push(item.clone());
            }else {
                not_finish.push(item.clone());
            }
        }
    }
    star.append(&mut not_finish);
    star
}
pub fn list_finish() -> Vec<Item> {
    let items = ITEMS.lock().unwrap();
    let mut finish: Vec<Item> = Vec::new();
    //items是一个MutexGuard对象。需要解引用获取原始类型
    //MutexGuard 对象拥有对内部数据的独占访问权，但是foreach会导致所有权转移，因此所以不能直接将其解引用并移出值，需要改用他的借用
    for item in &*items {
        if item.is_finish {
            finish.push(item.clone());
        }
    }
    finish
}


pub fn write_items_to_file(items: &Vec<Item>) -> Result<(), Error> {
    let mut file = File::create(file_path)?;

    for item in items {
        writeln!(
            file,
            "{}|{}|{}|{}|{}|{}|{}",
            item.id,
            item.title,
            item.desc,
            item.create_time,
            item.finish_time,
            item.is_star,
            item.is_finish
        )?;
    }

    Ok(())
}

pub fn read_items_from_file() -> Result<Vec<Item>, Error> {
    let file = File::open(file_path)?;
    let reader = BufReader::new(file);

    let mut items: Vec<Item> = Vec::new();

    for line in reader.lines() {
        let line = line?;
        let parts: Vec<&str> = line.split('|').collect();
        if parts.len() != 7 {
            return Err(Error::new(
                ErrorKind::InvalidData,
                "Invalid data format in file",
            ));
        }

        let id: u32 = parts[0].parse().map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid ID"))?;
        let title = String::from(parts[1]);
        let desc = String::from(parts[2]);
        let create_time = String::from(parts[3]);
        let finish_time = String::from(parts[4]);
        let is_star: bool = parts[5]
            .parse()
            .map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid is_star value"))?;
        let is_finish: bool = parts[6]
            .parse()
            .map_err(|_| Error::new(ErrorKind::InvalidData, "Invalid is_finish value"))?;

        let item = Item {
            id,
            title,
            desc,
            create_time,
            finish_time,
            is_star,
            is_finish,
        };

        items.push(item);
    }

    Ok(items)
}